use cpal::traits::HostTrait;
use cpal::Device;
use rdev::{simulate, EventType, Key, SimulateError};
use rodio::{source::Source, Decoder, DeviceTrait, OutputStream, Sink};
use std::alloc::System;
use std::fs::File;
use std::io::BufReader;
use std::sync::{Arc, Mutex};
use std::time::Duration;
use std::{thread, time, process};
use std::process::{Command, Child};
use windows_hotkeys::keys::{ModKey, VKey};
use windows_hotkeys::{HotkeyManager, HotkeyManagerImpl};
fn main() {
    let host = cpal::default_host();
    let mut device_finnal = host.default_output_device().unwrap();
    host.devices().unwrap().for_each(|device| {
        // println!("Device: {:?}", device.name().unwrap());
        if device.name().unwrap().contains("CABLE Input") {
            // println!();
            // println!("Found CABLE");
            device_finnal = device;
        }
        // println!();
    });
    let _ = thread::spawn(run_voice_stream);
    let _ = thread::spawn(zmp);
    println!("[****大喇叭 V1.0.0****]");
    let (_default_stream, _default_stream_handle) = OutputStream::try_default().unwrap();
    let (_stream, stream_handle) = OutputStream::try_from_device(&device_finnal).unwrap();

    let sink = Sink::try_new(&stream_handle).unwrap();
    sink.set_volume(0.3);
    let sink_us = Sink::try_new(&_default_stream_handle).unwrap();
    sink_us.set_volume(0.3);
    let shared_sink = Arc::new(Mutex::new(sink));
    let shared_sink_us = Arc::new(Mutex::new(sink_us));
    let mut hkm = HotkeyManager::new();

    // key 1
    let shared_sink_clone = shared_sink.clone();
    let shared_sink_us_clone = shared_sink_us.clone();
    let _ = hkm.register(VKey::Vk1, &[ModKey::Alt], move || {
        send(&EventType::KeyPress(Key::KeyV));
        play_sound(
            &shared_sink_clone.lock().unwrap(),
            &shared_sink_us_clone.lock().unwrap(),
            1,
        );
        send(&EventType::KeyRelease(Key::KeyV));
    });
    // key 2
    let shared_sink_clone1 = shared_sink.clone();
    let shared_sink_us_clone1 = shared_sink_us.clone();
    let _ = hkm.register(VKey::Vk2, &[ModKey::Alt], move || {
        send(&EventType::KeyPress(Key::KeyV));
        play_sound(
            &shared_sink_clone1.lock().unwrap(),
            &shared_sink_us_clone1.lock().unwrap(),
            2,
        );
        send(&EventType::KeyRelease(Key::KeyV));
    });

    // key 3
    let shared_sink_clone3 = shared_sink.clone();
    let shared_sink_us_clone3 = shared_sink_us.clone();
    let _ = hkm.register(VKey::Vk3, &[ModKey::Alt], move || {
        send(&EventType::KeyPress(Key::KeyV));
        play_sound(
            &shared_sink_clone3.lock().unwrap(),
            &shared_sink_us_clone3.lock().unwrap(),
            3,
        );
        send(&EventType::KeyRelease(Key::KeyV));
    });

    // key 4
    let shared_sink_clone4 = shared_sink.clone();
    let shared_sink_us_clone4 = shared_sink_us.clone();
    let _ = hkm.register(VKey::Vk4, &[ModKey::Alt], move || {
        send(&EventType::KeyPress(Key::KeyV));
        play_sound(
            &shared_sink_clone4.lock().unwrap(),
            &shared_sink_us_clone4.lock().unwrap(),
            4,
        );
        send(&EventType::KeyRelease(Key::KeyV));
    });

    // key 5
    let shared_sink_clone5 = shared_sink.clone();
    let shared_sink_us_clone5 = shared_sink_us.clone();
    let _ = hkm.register(VKey::Vk5, &[ModKey::Alt], move || {
        send(&EventType::KeyPress(Key::KeyV));
        play_sound(
            &shared_sink_clone5.lock().unwrap(),
            &shared_sink_us_clone5.lock().unwrap(),
            5,
        );
        send(&EventType::KeyRelease(Key::KeyV));
    });

    // key 6
    let shared_sink_clone6 = shared_sink.clone();
    let shared_sink_us_clone6 = shared_sink_us.clone();
    let _ = hkm.register(VKey::Vk6, &[ModKey::Alt], move || {
        send(&EventType::KeyPress(Key::KeyV));
        play_sound(
            &shared_sink_clone6.lock().unwrap(),
            &shared_sink_us_clone6.lock().unwrap(),
            6,
        );
        send(&EventType::KeyRelease(Key::KeyV));
    });

    // key 7
    let shared_sink_clone7 = shared_sink.clone();
    let shared_sink_us_clone7 = shared_sink_us.clone();
    let _ = hkm.register(VKey::Vk7, &[ModKey::Alt], move || {
        send(&EventType::KeyPress(Key::KeyV));
        play_sound(
            &shared_sink_clone7.lock().unwrap(),
            &shared_sink_us_clone7.lock().unwrap(),
            7,
        );
        send(&EventType::KeyRelease(Key::KeyV));
    });

    // key 8
    let shared_sink_clone8 = shared_sink.clone();
    let shared_sink_us_clone8 = shared_sink_us.clone();
    let _ = hkm.register(VKey::Vk8, &[ModKey::Alt], move || {
        send(&EventType::KeyPress(Key::KeyV));
        play_sound(
            &shared_sink_clone8.lock().unwrap(),
            &shared_sink_us_clone8.lock().unwrap(),
            8,
        );
        send(&EventType::KeyRelease(Key::KeyV));
    });

    // key 9
    let shared_sink_clone9 = shared_sink.clone();
    let shared_sink_us_clone9 = shared_sink_us.clone();
    let _ = hkm.register(VKey::Vk9, &[ModKey::Alt], move || {
        send(&EventType::KeyPress(Key::KeyV));
        play_sound(
            &shared_sink_clone9.lock().unwrap(),
            &shared_sink_us_clone9.lock().unwrap(),
            9,
        );
        send(&EventType::KeyRelease(Key::KeyV));
    });

    // key 10
    let shared_sink_clone10 = shared_sink.clone();
    let shared_sink_us_clone10 = shared_sink_us.clone();
    let _ = hkm.register(VKey::Vk0, &[ModKey::Alt], move || {
        send(&EventType::KeyPress(Key::KeyV));
        play_sound(
            &shared_sink_clone10.lock().unwrap(),
            &shared_sink_us_clone10.lock().unwrap(),
            10,
        );
        send(&EventType::KeyRelease(Key::KeyV));
    });

    // key 11
    let shared_sink_clone11 = shared_sink.clone();
    let shared_sink_us_clone11 = shared_sink_us.clone();
    let _ = hkm.register(VKey::Vk1, &[ModKey::Shift], move || {
        send(&EventType::KeyPress(Key::KeyV));
        play_sound(
            &shared_sink_clone11.lock().unwrap(),
            &shared_sink_us_clone11.lock().unwrap(),
            11,
        );
        send(&EventType::KeyRelease(Key::KeyV)); 
    });

    // key 12
    let shared_sink_clone12 = shared_sink.clone();
    let shared_sink_us_clone12 = shared_sink_us.clone();
    let _ = hkm.register(VKey::Vk2, &[ModKey::Shift], move || {
        send(&EventType::KeyPress(Key::KeyV));
        play_sound(
            &shared_sink_clone12.lock().unwrap(),
            &shared_sink_us_clone12.lock().unwrap(),
            12,
        );
        send(&EventType::KeyRelease(Key::KeyV));
    });

    // key 13
    let shared_sink_clone13 = shared_sink.clone();
    let shared_sink_us_clone13 = shared_sink_us.clone();
    let _ = hkm.register(VKey::Vk3, &[ModKey::Shift], move || {
        send(&EventType::KeyPress(Key::KeyV));
        play_sound(
            &shared_sink_clone13.lock().unwrap(),
            &shared_sink_us_clone13.lock().unwrap(),
            13,
        );
        send(&EventType::KeyRelease(Key::KeyV));
    });

    // key 14
    let shared_sink_clone14 = shared_sink.clone();
    let shared_sink_us_clone14 = shared_sink_us.clone();
    let _ = hkm.register(VKey::Vk4, &[ModKey::Shift], move || {
        send(&EventType::KeyPress(Key::KeyV));
        play_sound(
            &shared_sink_clone14.lock().unwrap(),
            &shared_sink_us_clone14.lock().unwrap(),
            14,
        );
        send(&EventType::KeyRelease(Key::KeyV));
    });

    // key 15
    let shared_sink_clone15 = shared_sink.clone();
    let shared_sink_us_clone15 = shared_sink_us.clone();
    let _ = hkm.register(VKey::Vk5, &[ModKey::Shift], move || {
        send(&EventType::KeyPress(Key::KeyV));
        play_sound(
            &shared_sink_clone15.lock().unwrap(),
            &shared_sink_us_clone15.lock().unwrap(),
            15,
        );
        send(&EventType::KeyRelease(Key::KeyV));
    });

    // key 16
    let shared_sink_clone16 = shared_sink.clone();
    let shared_sink_us_clone16 = shared_sink_us.clone();
    let _ = hkm.register(VKey::Vk6, &[ModKey::Shift], move || {
        send(&EventType::KeyPress(Key::KeyV));
        play_sound(
            &shared_sink_clone16.lock().unwrap(),
            &shared_sink_us_clone16.lock().unwrap(),
            16,
        );
        send(&EventType::KeyRelease(Key::KeyV));
    });

    // key 17
    let shared_sink_clone17 = shared_sink.clone();
    let shared_sink_us_clone17 = shared_sink_us.clone();
    let _ = hkm.register(VKey::Vk7, &[ModKey::Shift], move || {
        send(&EventType::KeyPress(Key::KeyV));
        play_sound(
            &shared_sink_clone17.lock().unwrap(),
            &shared_sink_us_clone17.lock().unwrap(),
            17,
        );
        send(&EventType::KeyRelease(Key::KeyV));
    });

    // key 18
    let shared_sink_clone18 = shared_sink.clone();
    let shared_sink_us_clone18 = shared_sink_us.clone();
    let _ = hkm.register(VKey::Vk8, &[ModKey::Shift], move || {
        send(&EventType::KeyPress(Key::KeyV));
        play_sound(
            &shared_sink_clone18.lock().unwrap(),
            &shared_sink_us_clone18.lock().unwrap(),
            18,
        );
        send(&EventType::KeyRelease(Key::KeyV));
    });

    // key 19
    let shared_sink_clone19 = shared_sink.clone();
    let shared_sink_us_clone19 = shared_sink_us.clone();
    let _ = hkm.register(VKey::Vk9, &[ModKey::Shift], move || {
        send(&EventType::KeyPress(Key::KeyV));
        play_sound(
            &shared_sink_clone19.lock().unwrap(),
            &shared_sink_us_clone19.lock().unwrap(),
            19,
        );
        send(&EventType::KeyRelease(Key::KeyV));
    });

    // key 20
    let shared_sink_clone20 = shared_sink.clone();
    let shared_sink_us_clone20 = shared_sink_us.clone();
    let _ = hkm.register(VKey::Vk0, &[ModKey::Shift], move || {
        send(&EventType::KeyPress(Key::KeyV));
        play_sound(
            &shared_sink_clone20.lock().unwrap(),
            &shared_sink_us_clone20.lock().unwrap(),
            20,
        );
        send(&EventType::KeyRelease(Key::KeyV));
    });
    hkm.event_loop();
}

fn play_sound(sink: &Sink, sink_us: &Sink, num: u32) {
    let mut path = String::from("./sounds/");
    path.push_str(num.to_string().as_str());
    path.push_str(".wav");
    let open_file = File::open(&path);
    if open_file.is_err() {
        println!("file not found");
        return;
    }

    let open_file1 = File::open(&path);
    if open_file1.is_err() {
        println!("file not found");
        return;
    }
    let file = BufReader::new(open_file.unwrap());
    let file1 = BufReader::new(open_file1.unwrap());
    // Decode that sound file into a source
    let source = Decoder::new(file).unwrap();
    let source1 = Decoder::new(file1).unwrap();
    sink.append(source);
    sink_us.append(source1);
    // The sound plays in a separate thread. This call will block the current thread until the sink
    // has finished playing all its queued sounds.
    sink.sleep_until_end();
    sink_us.sleep_until_end();
}

fn send(event_type: &EventType) {
    let delay = time::Duration::from_millis(60);
    match simulate(event_type) {
        Ok(()) => (),
        Err(SimulateError) => {
            println!("We could not send {:?}", event_type);
        }
    }
    // Let ths OS catchup (at least MacOS)
    thread::sleep(delay);
}


fn run_voice_stream(){
    let mut child: Child = Command::new("./voice_stream.exe").spawn().unwrap();
    let child_clone = Arc::new(Mutex::new(child));
    let child1 = child_clone.clone();
    let child2 = child_clone.clone();
    // child.kill().unwrap();
    ctrlc::set_handler(move || {
        print!("just close window to end this program");
        child2.lock().unwrap().kill().unwrap();
    }).expect("Error setting Ctrl-C handler");
    drop(child1.lock());
}


fn zmp(){
    let context = zmq::Context::new();
    let responder = context.socket(zmq::REP).unwrap();

    assert!(responder.bind("tcp://*:5555").is_ok());

    let mut msg = zmq::Message::new();

    loop {
        responder.recv(&mut msg, 0).unwrap();
        // println!("received: {}", msg.as_str().unwrap());
        let response: String = String::from("ok");
        responder.send(response.as_bytes(), 0).unwrap();
    }
}